#!/usr/sbin/perl
#                                                                         
#  Copyright (C) 1998, Silicon Graphics, Inc.                             
#  All Rights Reserved.                                                   
#                                                                         
#  UNPUBLISHED -- Rights reserved under the copyright laws of the United  
#  States.  Use of a copyright notice is precautionary only and does not  
#  imply publication or disclosure.                                       
#                                                                         
#  THIS SOFTWARE CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION OF     
#  SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION, DISTRIBUTION, OR 
#  DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN    
#  PERMISSION OF SILICON GRAPHICS, INC.                                   
#                                                                         
#  U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND                               
#  Use, duplication or disclosure by the Government is subject to         
#  restrictions as set forth in FAR 52.227.19(c)(2) or subparagraph       
#  (c)(1)(ii) of the Rights in Technical Data and Computer Software       
#  clause at DFARS 252.227-7013 and/or in similar or successor clauses    
#  in the FAR, or the DOD or NASA FAR Supplement.  Unpublished-- rights   
#  reserved under the copyright laws of the United States.                
#  Contractor/manufacturer is Silicon Graphics, Inc.,                     
#  2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.                 
#

# IP_address
#
# Get all resources for a particular type 
# and run the tests against that resource.

require "$LibDiagsPath/constants.pl";
require "$LibDiagsPath/libdiags.pl";
require "$LibDiagsPath/recurse.pl";

use Socket;

sub IP_address {
  local ($machine_name, $resource) = @_;
  local ($this);
  local (@list);
  local ($retv);

  &LogEntry();
  &Verbose("Running resource type %s tests on node %s",
	   $IP_ADDRESS,$machine_name);

  if ($resource eq "ALL") {
    @list=&GetResFromResType($machine_name,$IP_ADDRESS);
    if (scalar(@list) < 1) {
      &Failure("No resources found for resource type %s",$IP_ADDRESS);
      return $CD_FAILURE;
    }
    foreach $this (@list) {
      $retv=&TestIPaddress($machine_name,$this);

      # If the DESTRUCTIVE flag is set ...
      if ($DESTRUCTIVE) {
	  if (&ExecIPaddress($machine_name,$this) == $CD_FAILURE) {
	      &Failure("Resource %s of resource type %s failed",$this,
		       $IP_ADDRESS);
	      $retv=$CD_FAILURE;
	  }
      }
      &ExitStatus($retv);
    }
  } else {
    # We have been given the resource name.
    $retv=&TestIPaddress($machine_name, $resource);

    # If the DESTRUCTIVE flag is set ...
    if ($DESTRUCTIVE) {
	if (&ExecIPaddress($machine_name,$resource) == $CD_FAILURE) {
	    &Failure("Resource %s of resource type %s failed",$resource,
		     $IP_ADDRESS);
	    $retv=$CD_FAILURE;
	}
    }
    &ExitStatus($retv);
  }
  return $retv;
}

# ExecIPaddress
#    execute the resource scripts in order.
#    1) probe
#    2) exclusive
#    3) start
#    4) monitor
#    5) stop
#
sub ExecIPaddress {
    local ($node, $resource) = @_;
    local ($retv);

    &LogEntry();

    &Status("Starting resource %s of resource type %s on node %s",
	     $resource,$IP_ADDRESS,$node);
    
    # Only execute the destructive tests on this node.
    if (!&OnTheSameNode($node)) {
       &Notice("Can only execute the resource destructive tests on local host");
       &Log("Can only execute the resource destructive tests on local host %s/%s",
	      $this_host, $NodeToHost{$node});
       return $CD_SUCCESS;
    }

    &Status("Executing the $IP_ADDRESS resource scripts, I.e. probe, exclusive, start, monitor and  stop");
    &Status("Please be patient ...");
    foreach $script (@HA_LIST) {
	$retv=ExecuteScript($node,$resource,$IP_ADDRESS,$script);
	if ($retv == 0) {
	    # script failed, exit
	    return $CD_FAILURE;
	}
	# Sleep a while
	sleep(3);
    }
    return $CD_SUCCESS;
}

# TestIPaddress
# The resource test has three parts
#   1) Check the resource parameters.
#   2) If the resource has dependencies check them.

sub TestIPaddress {
  local ($machine_name, $resource) = @_;
  local ($retv);
  local ($addr,$net,$ifname,$braodcast);
  local (@parameters);
  local ($hostname);

  $retv=$CD_SUCCESS;

  &LogEntry();
  &Status("Testing resource %s of resource type %s on node %s",
	   $resource,$IP_ADDRESS,$machine_name);
  
  # Get the resource parameter set.
  @parameters=&GetResParameters($machine_name,$IP_ADDRESS,$resource);
  if (scalar(@parameters) < 1 ) {
    &Failure("No parameters returned for resource %s of resource type %s",
	     $resource,$IP_ADDRESS);
    return $CD_FAILURE;
  }
  if (@parameters[0] < 0){
    &Failure("No parameters found for resource %s of resource type %s",
	     $resource,$IP_ADDRESS);
    return $CD_FAILURE;
  }

  if (($net=&pulloff("NetworkMask",@parameters)) eq "") {
    &Failure("%s resource %s does not have the %s parameter set",
	     $IP_ADDRESS,$resource,"NetworkMask");
    $retv=$CD_FAILURE;
  }

  if (($broad=&pulloff("BroadcastAddress",@parameters)) eq "") {
    &Failure("%s resource %s does not have the %s parameter set",
	     $IP_ADDRESS,$resource,"BroadcastAddress");
    $retv=$CD_FAILURE;
  }

  if (($ifname=&pulloff("interfaces",@parameters)) eq "") {
    &Failure("%s resource %s does not have the %s parameter set",
	     $IP_ADDRESS,$resource,"interfaces");
    $retv=$CD_FAILURE;
  }

  if (!CheckIPSyntax($resource)) {
    &Failure("Resource %s has invalid IP_Address syntax %s",
	     $resource,$resource);
    $retv=$CD_FAILURE;
  }
  
  if (!CheckIPSyntax($broad)) {
    &Failure("Resource %s has invalid Broadcast syntax %s",
	     $resource,$broad);
    $retv=$CD_FAILURE;
  }
  
  if (!&CheckNetSyntax($net)) {
    &Failure("Resource %s has invalid Network mask %s\nIt should be in hexadecimal notation. Example: 0xffffff00 is a valid Network mask.\n",
	     $resource,$net);
    $retv=$CD_FAILURE;
  }
  
  if (!&CheckInterface($machine, $ifname)) {
    &Failure("Resource %s has unknown interface specification %s",
	     $resource,$ifname);
    $retv=$CD_FAILURE;
  }

  #Check that the ipaddress is valid and is known to the system
  if (!($hostname=gethostbyname($resource,AF_INET))) {
    &Failure("Invalid resource %s of resource type %s",$resource,$IP_ADDRESS);
    $retv=$CD_FAILURE;
  }
 
  return $retv;
}
